#include "iapsessclient.h"
#include "clientservercommon.h"

#include <e32debug.h>
#include <w32std.h>
#include <e32cmn.h>
#include <mw/eikappui.h>
#include <mw/apgtask.h>
#include <mw/APGWGNAM.H>

static TInt CreateServerProcess();

// CONSTANTS
// Number of message slots to reserve for this client server session.
// Since we only communicate synchronously here, we never have any
// outstanding asynchronous requests.
static const TUint KDefaultMessageSlots = 0;

RIAPSessClient* RIAPSessClient::NewL()
	{
	RIAPSessClient* self = new (ELeave) RIAPSessClient();
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
	return self;
	}

void RIAPSessClient::ConstructL()
	{
	}

RIAPSessClient::RIAPSessClient():
	RSessionBase(),
	iState(EIdleState)
	{
	}

RIAPSessClient::~RIAPSessClient()
	{
	}

TInt RIAPSessClient::Connect()
    {
    TInt error = StartIAPServer();

    if(KErrNone == error)
        {
        error = CreateSession(KIAPServerName,
                              Version(),
                              KDefaultMessageSlots);
        }
    return error;
    }

TVersion RIAPSessClient::Version() const
    {
    return(TVersion(KIAPServMajorVersionNumber,
                    KIAPServMinorVersionNumber,
                    KIAPServBuildVersionNumber));
    }

TInt RIAPSessClient::StartIAPServer()
	{
    TInt result;

    TFindServer findServer(KIAPServerName);
    TFullName name;

    result = findServer.Next(name);
    if(result == KErrNone)
        {
        // Server already running
        return KErrNone;
        }

    RSemaphore semaphore;
    result = semaphore.CreateGlobal(KIAPServerSemaphoreName, 0);
    if(result != KErrNone)
        {
        return  result;
        }

    result = CreateServerProcess();
    if(result != KErrNone)
        {
        return  result;
        }

    semaphore.Wait();
    semaphore.Close();

    return KErrNone;
	}

TInt CreateServerProcess()
	{
	const TUidType serverUid(KNullUid, KNullUid, KServerUid3);
	RProcess server;

	TInt result = server.Create(KIAPServerFileName, KNullDesC, serverUid);
	if(result != KErrNone)
		{
		return result;
		}

	server.Resume();
	server.Close();

	return KErrNone;
	}

HBufC8* RIAPSessClient::getAuthDigestLC()
	{
	TIAPrequestData data;
	data.appWinGroup = getThisWingroupID();
    TPckgBuf<TIAPrequestData> pkg(data);
    TIpcArgs args(&pkg);
    
    RDebug::Print( _L("EIAPServUserAndData started..."));
    SendCommandL(EIAPServUserAndData, args);
    RDebug::Print( _L("EIAPServUserAndData ...done"));
	TIAPrequestData& result = pkg();
    RDebug::RawPrint(result.payload);
    
    return (result.payload.AllocLC());
	}

HBufC8* RIAPSessClient::purchaseProductLC(const TDesC8& aProdId)
	{
	TIAPrequestData data;
	data.appWinGroup = getThisWingroupID();
	data.payload.Copy(aProdId);
    TPckgBuf<TIAPrequestData> pkg(data);
    TIpcArgs args(&pkg);
        
    RDebug::Print( _L("EIAPServPurcase started..."));
    SendCommandL(EIAPServPurcase, args);
    RDebug::Print( _L("EIAPServPurcase ...done"));
	TIAPrequestData& result = pkg();
    RDebug::RawPrint(result.payload);
   
	return (result.payload.AllocLC());
	}

void RIAPSessClient::getProductDataL(const TDesC8& aProdId, RPointerArray<HBufC8>& aResult)
	{
	TProductData product;
	product.productId = aProdId;
	product.appWinGroup = getThisWingroupID(); 
	TPckgBuf<TProductData>pckg(product);
    TIpcArgs args(&pckg);
    
    RDebug::Print( _L("EIAPServProductData started ..."));
    SendCommandL(EIAPServProductData, args);

    TProductData& data = pckg();
    aResult.Reset();
    aResult.AppendL(data.productInformation.AllocLC());
    aResult.AppendL(data.description.AllocLC());
    aResult.AppendL(data.shortDescription.AllocLC());
    aResult.AppendL(data.price.AllocLC());
    
    RDebug::Print( _L("EIAPServProductData ...done"));
    RDebug::RawPrint(data.productInformation);
    RDebug::RawPrint(data.description);
    RDebug::RawPrint(data.shortDescription);
    RDebug::RawPrint(data.price);
   
    CleanupStack::Pop(4);
	}

void RIAPSessClient::SendCommandL(TIAPServRqst aCmd, TIpcArgs& args)
	{
    iState = EBusyState;
    User::LeaveIfError(SendReceive(aCmd, args));
    iState = EIdleState;
	}

TInt RIAPSessClient::getThisWingroupID()
	{
    TApaTaskList taskList(CCoeEnv::Static()->WsSession());
    TApaTask task = taskList.FindByPos(0); 
    return (task.WgId());
	}
